package com.alibaba.citrus.cr.platform.enhance.facade.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import com.alibaba.acm.shaded.com.alibaba.metrics.StringUtils;
import com.alibaba.citrus.cr.common.annotation.FacadeInvoker;
import com.alibaba.citrus.cr.common.exception.FacadeException;
import com.alibaba.citrus.cr.common.util.PageUtils;
import com.alibaba.citrus.cr.platform.enhance.repository.CustomerAddressRelationRepository;
import com.alibaba.citrus.cr.platform.enhance.repository.CustomerAddressRepository;
import com.alibaba.citrus.cr.platform.enhance.repository.CustomerSaleScopeRepository;
import com.alibaba.cz.base.tool.StringUtil;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;

import com.epoch.app.bcorder.model.dto.GetEmployeeSelectRequest;
import com.epoch.app.bcorder.model.dto.GetEmployeeSelectResponse;
import com.epoch.app.bcorder.model.dto.GetOrganizationSelectsRequest;
import com.epoch.app.bcorder.model.dto.GetOrganizationSelectsResponse;
import com.epoch.app.bcorder.service.BaseDataService;
import com.epoch.app.crplatformenhance.api.customersalescopequery.dto.BatchQueryCustomerSaleScopeRequest;
import com.epoch.app.crplatformenhance.api.customersalescopequery.dto.QueryCustomerScopeDetailRequest;
import com.epoch.app.crplatformenhance.api.customersalescopequery.dto.QuerySaleScopeByIdRequest;
import com.epoch.app.crplatformenhance.api.customersalescopequery.dto.QuerySaleScopeListByRelationIdRequest;
import com.epoch.app.crplatformenhance.api.customersalescopequery.service.CustomerSaleScopeQueryService;
import com.epoch.app.crplatformenhance.api.organizationquery.service.OrganizationQueryService;
import com.epoch.app.crplatformenhance.domain.customersalescope.dto.BatchQueryByIdsRequest;
import com.epoch.app.crplatformenhance.dto.request.IdQueryRequest;
import com.epoch.app.crplatformenhance.dto.request.QuerySaleScopeRequest;
import com.epoch.app.crplatformenhance.dto.request.SimpleQueryAddressRequest;
import com.epoch.app.crplatformenhance.enums.OrganizationTypeEnum;
import com.epoch.app.crplatformenhance.model.dto.CustomerAddressRelationLoadListRequest;
import com.epoch.app.crplatformenhance.model.dto.CustomerAddressRelationSDO;
import com.epoch.app.crplatformenhance.model.dto.PageQueryCustomerScopeRequest;
import com.epoch.app.crplatformenhance.model.dto.PageQueryCustomerScopeResponse;
import com.epoch.app.crplatformenhance.model.enums.CustomerRelationBizTypeEnum;
import com.epoch.app.crplatformenhance.sdo.CustomerAddressSDO;
import com.epoch.app.crplatformenhance.sdo.CustomerSaleScopeSDO;
import com.epoch.app.crplatformenhance.sdo.OrganizationSDO;
import com.epoch.app.crplatformenhance.service.CrPlatformEnhanceService;
import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

@Primary
@Service
public class CustomerSaleScopeQueryServiceImpl implements CustomerSaleScopeQueryService {

    @Resource
    private CustomerSaleScopeRepository saleScopeRepository;

    @Resource
    private CustomerAddressRepository addressRepository;

    @Resource
    private CustomerAddressRelationRepository customerAddressRelationRepository;

    @Resource
    private CrPlatformEnhanceService crPlatformEnhanceService;

    @Resource
    private OrganizationQueryService organizationQueryService;

    @Resource
    private BaseDataService baseDataService;

    @Override
    @FacadeInvoker
    public Result<List<CustomerSaleScopeSDO>> querySaleScopeList(CustomerSaleScopeSDO saleScopeSDO) {
        List<CustomerSaleScopeSDO> saleScopeList = saleScopeRepository.queryList(saleScopeSDO);
        return Result.success(saleScopeList);
    }

    @Override
    @FacadeInvoker
    public Result<List<CustomerSaleScopeSDO>> pageQuerySaleScope(QuerySaleScopeRequest request) {
        PageResult<List<CustomerSaleScopeSDO>> saleScopeList = saleScopeRepository.pageQuery(request);
        return Result.listSuccess(saleScopeList.getContent(), saleScopeList.getTotal());
    }

    @Override
    @FacadeInvoker
    public Object queryCustomerScopeDetail(QueryCustomerScopeDetailRequest queryCustomerScopeDetailRequest) {
        String id = queryCustomerScopeDetailRequest.getId();
        if(StringUtils.isBlank(id)) {
            throw new FacadeException("OTS-01-004-02-16-009");
        }
        PageQueryCustomerScopeRequest request = new PageQueryCustomerScopeRequest();
        request.setId(id);
        PageQueryCustomerScopeResponse pageQueryCustomerScopeResponse = crPlatformEnhanceService.pageQueryCustomerScope(request);
        if(null == pageQueryCustomerScopeResponse) {
            throw new FacadeException("OTS-01-004-02-16-015");
        }
        List<Map> resultList = pageQueryCustomerScopeResponse.getResult();
        if(CollectionUtils.isEmpty(resultList)) {
            throw new FacadeException("OTS-01-004-02-16-016");
        }
        Map customerSaleScopeSDO = resultList.get(0);
        // 销售组织
        String orgSaleOrganizationCode = customerSaleScopeSDO.get("orgSaleOrganizationCode").toString();
        String orgSaleChannelCode = customerSaleScopeSDO.get("orgSaleChannelCode")!=null?customerSaleScopeSDO.get("orgSaleChannelCode").toString():null;
        String orgSaleDepartmentCode = customerSaleScopeSDO.get("orgSaleDepartmentCode")!=null?customerSaleScopeSDO.get("orgSaleDepartmentCode").toString():null;

        Map<String, Object> resultSDO = new HashMap<>();
        // 获取销售组织下的销售渠道列表
        if(StringUtils.isNotBlank(orgSaleChannelCode)) {
            List<String> channelCodeList = getList(orgSaleOrganizationCode);
            if (CollectionUtils.isEmpty(channelCodeList) || !channelCodeList.contains(orgSaleChannelCode)) {
                customerSaleScopeSDO.put("orgSalesChannelName", "");
                customerSaleScopeSDO.put("orgSalesDepartmentName", "");
                customerSaleScopeSDO.put("principalName", "");
                customerSaleScopeSDO.put("orgSaleChannelCode", "");
                customerSaleScopeSDO.put("orgSaleDepartmentCode", "");
                customerSaleScopeSDO.put("principal", "");
                resultSDO.put("result", customerSaleScopeSDO);
                return resultSDO;
            }
        }
        // 获取销售组织下的销售渠道列表
        if(StringUtils.isNotBlank(orgSaleDepartmentCode)){
            List<String> departmentCodeList = getList(orgSaleChannelCode);
            if (CollectionUtils.isEmpty(departmentCodeList) || !departmentCodeList.contains(orgSaleDepartmentCode)) {
                customerSaleScopeSDO.put("orgSalesDepartmentName", "");
                customerSaleScopeSDO.put("principalName", "");
                customerSaleScopeSDO.put("orgSaleDepartmentCode", "");
                customerSaleScopeSDO.put("principal", "");
                resultSDO.put("result",customerSaleScopeSDO);
                return resultSDO;
            }
            // 获取部门下的负责人
            GetEmployeeSelectRequest getEmployeeSelectRequest = new GetEmployeeSelectRequest();
            getEmployeeSelectRequest.setId(orgSaleDepartmentCode);
            GetEmployeeSelectResponse employeeSelect = baseDataService.getEmployeeSelect(getEmployeeSelectRequest);
            if (null == employeeSelect) {
                throw new FacadeException("OTS-01-004-02-16-017");
            }
            List employeeResult = employeeSelect.getResult();
            if (CollectionUtils.isEmpty(employeeResult)) {
                customerSaleScopeSDO.put("principalName", "");
                customerSaleScopeSDO.put("principal", "");
                resultSDO.put("result",customerSaleScopeSDO);
            }
            List<Map> employeeList = JSONObject.parseArray(JSON.toJSONString(employeeResult), Map.class);
            List<String> employeeCodeList = employeeList.stream().map(map -> map.get("value").toString()).collect(Collectors.toList());
            if (Objects.isNull(customerSaleScopeSDO.get("principal"))) {
                resultSDO.put("result",customerSaleScopeSDO);
                return resultSDO;
            }

            String principal = customerSaleScopeSDO.get("principal")!=null?customerSaleScopeSDO.get("principal").toString():null;
            if(StringUtil.isNotEmpty(principal)){
                if(!employeeCodeList.contains(principal)) {
                    customerSaleScopeSDO.put("principalName", "");
                    customerSaleScopeSDO.put("principal", "");
                    resultSDO.put("result",customerSaleScopeSDO);
                    return resultSDO;
                }
            }
        }

        // 查询售达方客户负责人
        CustomerAddressRelationLoadListRequest relationLoadListRequest = new CustomerAddressRelationLoadListRequest();
        relationLoadListRequest.setAddressId(String.valueOf(customerSaleScopeSDO.get("id")));
        relationLoadListRequest.setAddressCode((String) customerSaleScopeSDO.get("addressCode"));
        relationLoadListRequest.setBizType(CustomerRelationBizTypeEnum.SALESCOPE_CUSTOMER_PRINCIPAL_RELATION.getValue());
        List<CustomerAddressRelationSDO> list = customerAddressRelationRepository.queryRelationList(relationLoadListRequest);
        if(org.apache.commons.collections4.CollectionUtils.isNotEmpty(list)){
            customerSaleScopeSDO.put("customerPrincipalList",list.stream().map(x->x.getRelationId()).collect(Collectors.toList()));
        }

        resultSDO.put("result",customerSaleScopeSDO);
        return resultSDO;
    }

    @NotNull
    private List<String> getList(String parentId) {
        GetOrganizationSelectsRequest getOrganizationSelectsRequest = new GetOrganizationSelectsRequest();
        getOrganizationSelectsRequest.setParentId(parentId);
        GetOrganizationSelectsResponse organizationSelects = baseDataService.getOrganizationSelects(getOrganizationSelectsRequest);
        if (null == organizationSelects) {
            return Lists.newArrayList();
        }
        List result = organizationSelects.getResult();
        if (CollectionUtils.isEmpty(result)) {
            return Lists.newArrayList();
        }
        List<Map> list = JSONObject.parseArray(JSON.toJSONString(result), Map.class);
        List<String> codeList = list.stream().map(map -> map.get("value").toString()).collect(Collectors.toList());
        return codeList;
    }

    @Override
    public Result<List<CustomerSaleScopeSDO>> batchQueryCustomerSaleScope(BatchQueryCustomerSaleScopeRequest batchQueryCustomerSaleScopeRequest) {
        List<CustomerSaleScopeSDO> scopeSDOS = saleScopeRepository.batchQueryCustomerSaleScopeByCustomerCodes(batchQueryCustomerSaleScopeRequest);
        return Result.success(scopeSDOS);
    }

    @Override
    public Result<List<CustomerSaleScopeSDO>> querySaleScopeListByRelationId(QuerySaleScopeListByRelationIdRequest querySaleScopeListByRelationIdRequest) {
        CustomerAddressRelationLoadListRequest relationLoadListRequest = new CustomerAddressRelationLoadListRequest();
        if (StringUtils.isNotBlank(querySaleScopeListByRelationIdRequest.getRelationEmployeeId())) {
            relationLoadListRequest.setRelationId(querySaleScopeListByRelationIdRequest.getRelationEmployeeId());
        }
        relationLoadListRequest.setBizType(CustomerRelationBizTypeEnum.SALESCOPE_CUSTOMER_PRINCIPAL_RELATION.getValue());
        List<CustomerAddressRelationSDO> relationList = customerAddressRelationRepository.queryRelationList(relationLoadListRequest);
        if (CollectionUtils.isEmpty(relationList)) {
            return Result.listEmptySuccess();
        }

        List<String> customerSaleScopeIds = relationList.stream().map(x->x.getAddressId()).distinct().collect(Collectors.toList());
        // 当前的数据量，不支持分页不支持客户名称搜索，能满足需求
        // customer_index是客户档案与客户售达方关联ES 只有客户档案id，没有客户售达方id，ES用不了，DB不建议客户名称模糊查询
        BatchQueryByIdsRequest querySaleScopeRequest = new BatchQueryByIdsRequest();
        querySaleScopeRequest.setIds(customerSaleScopeIds);
        querySaleScopeRequest.setStatus(querySaleScopeListByRelationIdRequest.getStatus());
//        querySaleScopeRequest.setCustomerNameLike();
//        querySaleScopeRequest.setStart();
//        querySaleScopeRequest.getLimit();
        if (querySaleScopeListByRelationIdRequest.getRelatedOrganizationType() != null && StringUtils.isNotBlank(querySaleScopeListByRelationIdRequest.getRelatedOrganizationId())) {
            if (OrganizationTypeEnum.REGION.getCode().equals(querySaleScopeListByRelationIdRequest.getRelatedOrganizationType())) {
                IdQueryRequest queryDownOrgReq = new IdQueryRequest();
                queryDownOrgReq.setId(querySaleScopeListByRelationIdRequest.getRelatedOrganizationId());
                queryDownOrgReq.setType(OrganizationTypeEnum.COMPANY.getCode());
                Result<List<OrganizationSDO>> orgResult = organizationQueryService.getDownQueryOrganization(queryDownOrgReq);
                if (orgResult==null || CollectionUtils.isEmpty(orgResult.getResult())) {
                    return Result.listEmptySuccess();
                }
                List<String> orgBussinessUnitIdList = orgResult.getResult().stream().map(x->x.getId()).collect(Collectors.toList());
                querySaleScopeRequest.setOrgBussinessUnitCodeList(orgBussinessUnitIdList);
            }else if (OrganizationTypeEnum.COMPANY.getCode().equals(querySaleScopeListByRelationIdRequest.getRelatedOrganizationType())) {
                querySaleScopeRequest.setOrgBussinessUnitCodeList(Lists.newArrayList(querySaleScopeListByRelationIdRequest.getRelatedOrganizationId()));
            }else if(OrganizationTypeEnum.SALES_ORGANIZATION.getCode().equals(querySaleScopeListByRelationIdRequest.getRelatedOrganizationType())) {
                querySaleScopeRequest.setOrgSaleOrganizationCode(querySaleScopeListByRelationIdRequest.getRelatedOrganizationId());
            }
        }
        List<CustomerSaleScopeSDO> customerSaleScopeList = saleScopeRepository.batchQueryCustomerSaleScopeByIds(querySaleScopeRequest);

        // 由于售达方不会维护渠道、部门组织，通过送达方数据控制数据权限。
        // 根据渠道或部门组织查询送达方得到的客户编码数据太多，查询条件太长，在这里筛选
        if (querySaleScopeListByRelationIdRequest.getRelatedOrganizationType() != null && StringUtils.isNotBlank(querySaleScopeListByRelationIdRequest.getRelatedOrganizationId())
               && querySaleScopeListByRelationIdRequest.getRelatedOrganizationType() > OrganizationTypeEnum.SALES_ORGANIZATION.getCode()) {
            int pageSize = 1000;
            List<CustomerAddressSDO> customerAddressList = new ArrayList<>();
            SimpleQueryAddressRequest queryAddressRequest = new SimpleQueryAddressRequest();
            if(OrganizationTypeEnum.SALES_CHANNEL.getCode().equals(querySaleScopeListByRelationIdRequest.getRelatedOrganizationType())) {
                queryAddressRequest.setOrgSaleChannelCode(querySaleScopeListByRelationIdRequest.getRelatedOrganizationId());
            }else if(OrganizationTypeEnum.SALES_DEPARTMENT.getCode().equals(querySaleScopeListByRelationIdRequest.getRelatedOrganizationType())) {
                queryAddressRequest.setOrgSaleDepartmentCode(querySaleScopeListByRelationIdRequest.getRelatedOrganizationId());
            }
            queryAddressRequest.setStatus(1);
            queryAddressRequest.setStart(0);
            queryAddressRequest.setLimit(pageSize);
            PageResult<List<CustomerAddressSDO>> pageResult = addressRepository.simplePageQuery(queryAddressRequest);
            if (pageResult != null && org.apache.commons.collections4.CollectionUtils.isNotEmpty(pageResult.getContent())) {
                customerAddressList.addAll(pageResult.getContent());

                int total = pageResult.getTotal();
                if (total>pageSize) {
                    int totalPage = PageUtils.getTotalPage(total,pageSize);
                    for (int page = 1; page < totalPage; page++) {
                        int start = page*pageSize;
                        queryAddressRequest.setStart(start);
                        queryAddressRequest.setLimit(pageSize);
                        PageResult<List<CustomerAddressSDO>> pageResult2 = addressRepository.simplePageQuery(queryAddressRequest);
                        if (pageResult2 != null && org.apache.commons.collections4.CollectionUtils.isNotEmpty(pageResult2.getContent())) {
                            customerAddressList.addAll(pageResult2.getContent());
                        }
                    }
                }
            }

            List<String> customerCodes = customerAddressList.stream().map(x->x.getCustomerCode()).distinct().collect(Collectors.toList());

            customerSaleScopeList = customerSaleScopeList.stream().filter(x->customerCodes.contains(x.getCustomerCode())).collect(Collectors.toList());
        }

        //搜索过滤
//        String searchCustomer = querySaleScopeListByRelationIdRequest.getSearchCustomer();
//        if (StringUtils.isNotBlank(searchCustomer)) {
//            customerSaleScopeList = customerSaleScopeList.stream()
//                    .filter(x->x.getCustomerCode().contains(searchCustomer) || x.getCustomerName().contains(searchCustomer)).collect(Collectors.toList());
//            return Result.listSuccess(customerSaleScopeList,customerSaleScopeList.size());
//        }
        return Result.listSuccess(customerSaleScopeList,customerSaleScopeList.size());
    }

    @Override
    public Result<CustomerSaleScopeSDO> querySaleScopeById(QuerySaleScopeByIdRequest querySaleScopeByIdRequest) {
        CustomerSaleScopeSDO saleScopeSDO = saleScopeRepository.load(querySaleScopeByIdRequest.getId());
        return Result.success(saleScopeSDO);
    }

}
